﻿using System;
using System.ServiceModel;
using System.Collections;
using System.Text;
using System.ServiceModel.Security;

namespace Blank.wcf.ClientConnectLib
{
    internal static class ChannelFactoryCreator
    {
        #region Fileds
        private static string address;
        private static string userName;
        private static string password;
        private static WSHttpBinding wsHttpBinding;
        private static EndpointAddress endpointAddress;
        #endregion
        #region Properties
        public static WSHttpBinding WsHttpBinding
        {
            get { return wsHttpBinding; }
            set { wsHttpBinding = value; }
        }
        public static string Password
        {
            get { return password; }
            set { password = value; }
        }
        public static string UserName
        {
            get { return userName; }
            set { userName = value; }
        }
        public static string Address
        {
            get { return address; }
            set { address = value; }
        }
        public static EndpointAddress EndpointAddress
        {
            get { return endpointAddress; }
            set { endpointAddress = value; }
        }
        #endregion
        private static Hashtable channelFactories = new Hashtable();
        /// <summary>
        /// 初始化会话和终极点地址
        /// </summary>
        public static void Invoke()
        {
            wsHttpBinding = new WSHttpBinding();
            wsHttpBinding.Name = "WSHttpBinding_IMainContract";
            wsHttpBinding.MaxBufferPoolSize = 2147483647;
            wsHttpBinding.MaxReceivedMessageSize = 2147483647;
            wsHttpBinding.TextEncoding = Encoding.UTF8;
            wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
            wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;

            wsHttpBinding.TransactionFlow = false;
            wsHttpBinding.BypassProxyOnLocal = false;
            wsHttpBinding.UseDefaultWebProxy = true;
            //表示接受Cookies
            wsHttpBinding.AllowCookies = false;

            wsHttpBinding.CloseTimeout = new TimeSpan(0, 3, 0);
            wsHttpBinding.OpenTimeout = new TimeSpan(0, 3, 0);
            wsHttpBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            wsHttpBinding.SendTimeout = new TimeSpan(0, 3, 0);

            wsHttpBinding.ReaderQuotas.MaxDepth = 32;
            wsHttpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
            wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
            wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
            wsHttpBinding.ReaderQuotas.MaxArrayLength = 2147483647;

            wsHttpBinding.ReliableSession.Ordered = true;
            wsHttpBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 10, 0);
            wsHttpBinding.ReliableSession.Enabled = false;

#if !useSecurity
            wsHttpBinding.Security.Mode = SecurityMode.None;
            wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
            wsHttpBinding.Security.Message.NegotiateServiceCredential = true;
            wsHttpBinding.Security.Message.EstablishSecurityContext = true;
            EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity("MainService");
            endpointAddress = new EndpointAddress(new Uri(Address), identity);
#else
            wsHttpBinding.Security.Mode = SecurityMode.Message;
            wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
            wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
            wsHttpBinding.Security.Message.NegotiateServiceCredential = true;
            wsHttpBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
            EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity("MainService");
            endpointAddress = new EndpointAddress(new Uri(Address), identity);
#endif

        }

        public static ChannelFactory<T> Create<T>(string endpointName)
        {
            if (string.IsNullOrEmpty(endpointName))
            {
                throw new ArgumentNullException("endpointName");
            }
            ChannelFactory<T> channelFactory = null;
            if (channelFactories.ContainsKey(endpointName))
            {
                channelFactory = channelFactories[endpointName] as ChannelFactory<T>;
            }
            if (channelFactory == null)
            {
                channelFactory = new ChannelFactory<T>(WsHttpBinding, EndpointAddress);
#if !useSecurity
                ;
#else

                channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
                channelFactory.Credentials.UserName.UserName = UserName;
                channelFactory.Credentials.UserName.Password = Password;
#endif
                channelFactory.Endpoint.Name = endpointName;
                channelFactory.Endpoint.Contract.ContractType = typeof(T);

                lock (channelFactories.SyncRoot)
                {
                    channelFactories[endpointName] = channelFactory;
                }
            }
            return channelFactory;
        }
    }
}
